﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ProjectMeetingActioner.cs" company="DissingNelleman">
//   
// All rights reserved. </copyright>
// <summary>
//   The project meeting actioner.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ServiceLibrary.Actioners.Activities
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    using NHibernate;
    using NHibernate.Criterion;

    using ServiceLibrary.Models.Domain;
    using ServiceLibrary.Services.Commands;
    using ServiceLibrary.Services.Queries;
    using ServiceLibrary.Services.Results;

    /// <summary>
    /// The project meeting actioner.
    /// </summary>
    public class ProjectMeetingActioner : ActionerBase
    {
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ProjectMeetingActioner"/> class.
        /// </summary>
        /// <param name="session">
        /// The session.
        /// </param>
        /// <param name="activeUser">
        /// The active user.
        /// </param>
        public ProjectMeetingActioner(ISession session, User activeUser)
            : base(session, activeUser)
        {
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// The create default project meeting related types.
        /// </summary>
        public void CreateDefaultProjectMeetingRelatedTypes()
        {
            const string Puljer = "Puljer & fonde";
            const string OtherFinancing = "Anden finansiering";

            IList<FundType> fundTypes = this.Session.QueryOver<FundType>().List();

            var puljerFundType = new FundType { ID = Guid.Empty };
            bool alreadyExists = (from f in fundTypes where f.Name.Equals(Puljer) select f).Any();
            if (!alreadyExists)
            {
                puljerFundType = new FundType { ID = Guid.NewGuid(), Name = Puljer };
                this.Session.Save(puljerFundType);
            }

            IList<Fund> funds = this.Session.QueryOver<Fund>().List();

            if (puljerFundType.ID != Guid.Empty)
            {
                var defaultFunds = new List<string>
                                       {
                                           "Opi-pulje", 
                                           "Markedsmodningsfond", 
                                           "Højteknologifond", 
                                           "Regionalfond", 
                                           "Socialfond", 
                                           "Øvrige nationale fonde", 
                                           "EU-fonde", 
                                           "Øvrige internationale fonde"
                                       };

                foreach (string fund in defaultFunds)
                {
                    alreadyExists = funds.Any(f => f.Name.Equals(fund));
                    if (!alreadyExists)
                    {
                        var newfund = new Fund { ID = Guid.NewGuid(), Name = fund, Type = puljerFundType };
                        this.Session.Save(newfund);
                    }
                }
            }

            var otherFinancingFundType = new FundType { ID = Guid.Empty };
            alreadyExists = (from f in fundTypes where f.Name.Equals(OtherFinancing) select f).Any();
            if (!alreadyExists)
            {
                otherFinancingFundType = new FundType { ID = Guid.NewGuid(), Name = OtherFinancing };
                this.Session.Save(otherFinancingFundType);
            }

            if (otherFinancingFundType.ID != Guid.Empty)
            {
                var defaultFunds = new List<string> { "WT invest", "Accelerace", "Vækstfonden", "SDTI" };

                foreach (string fund in defaultFunds)
                {
                    alreadyExists = funds.Any(f => f.Name.Equals(fund));
                    if (!alreadyExists)
                    {
                        var newfund = new Fund { ID = Guid.NewGuid(), Name = fund, Type = otherFinancingFundType };
                        this.Session.Save(newfund);
                    }
                }
            }

            var defaultDemonstrations = new List<string>
                                            {
                                                "Demostrationstest/Konceptvalidering", 
                                                "Innovationstest/Udviklingsafprøvning", 
                                                "Vejledning i udvikling af prototype", 
                                                "Understøttelse af brug af WT innovation", 
                                                "Vejledning om OPI-best practice",
                                                "Projektansøgningsgrupper"
                                            };

            IList<ProjectMeetingDemonstration> demonstrations =
                this.Session.QueryOver<ProjectMeetingDemonstration>().List();
            foreach (string demo in defaultDemonstrations)
            {
                alreadyExists = demonstrations.Any(d => d.Name.Equals(demo));
                if (!alreadyExists)
                {
                    var newDemo = new ProjectMeetingDemonstration { ID = Guid.NewGuid(), Name = demo };
                    this.Session.Save(newDemo);
                }
            }

            var defaultRoles = new List<string>
                                   {
                                       "Projektleder", 
                                       "Delprojektleder", 
                                       "Arbejdspakkeleder", 
                                       "Deltager", 
                                       "Partner", 
                                       "Netværkspartner"
                                   };
            IList<ProjectMeetingRole> roles = this.Session.QueryOver<ProjectMeetingRole>().List();
            foreach (string role in defaultRoles)
            {
                alreadyExists = roles.Any(r => r.Name.Equals(role));
                if (!alreadyExists)
                {
                    var newRole = new ProjectMeetingRole { ID = Guid.NewGuid(), Name = role };
                    this.Session.Save(newRole);
                }
            }

            var defaultResearchAndDevelopments = new Dictionary<string, bool>
                                                     {
                                                         { "Proukter/teknologi", true }, 
                                                         { "Service", true }, 
                                                         { "Test og tilpasning", false }, 
                                                         { "Intelligent indkøb/udbud", false }, 
                                                         {
                                                             "Udvikling kurser/uddannelsesforløb", 
                                                             false
                                                         }, 
                                                         { "Inkubator/iværksætter", false }, 
                                                         { "Andet", false }
                                                     };

            IList<ProjectType> types = this.Session.QueryOver<ProjectType>().List();
            foreach (string name in defaultResearchAndDevelopments.Keys)
            {
                alreadyExists = types.Any(r => r.Name.Equals(name));
                if (!alreadyExists)
                {
                    var newType = new ProjectType
                                      {
                                          ID = Guid.NewGuid(), 
                                          Name = name, 
                                          IsResearchAndDevelopment = defaultResearchAndDevelopments[name]
                                      };
                    this.Session.Save(newType);
                }
            }

            IList<Group> existingGroups = this.Session.QueryOver<Group>().List();
            var defaultGroups = new List<string> { "Taskforce", "Arbejdsgrupper", "Projektansøgningsgrupper" };
            foreach (string name in defaultGroups)
            {
                alreadyExists = existingGroups.Any(g => g.Name.Equals(name));
                if (!alreadyExists)
                {
                    var newGroup = new Group { ID = Guid.NewGuid(), Name = name };
                    this.Session.Save(newGroup);
                }
            }
        }

        /// <summary>
        /// The create project meeting.
        /// </summary>
        /// <param name="meeting">
        /// The meeting.
        /// </param>
        /// <returns>
        /// The <see cref="Guid"/>.
        /// </returns>
        public Guid CreateProjectMeeting(ProjectMeeting meeting)
        {
            
            if (meeting.Status != null)
            {
                meeting.Status.CreatedDateTime = DateTime.Now;
                this.Session.Save(meeting.Status);
            }

            meeting.CreatedDateTime = DateTime.Now;
            this.Session.Save(meeting);
            this.Log.CreateLogEntry(
                meeting.ID,
                string.Format("Projekt-aktivitet '{0}' blev oprettet.", meeting.Name),
                Enums.LogEntryType.ProjectMeeting);

            return meeting.ID;
        }

        /// <summary>
        /// The execute search query.
        /// </summary>
        /// <param name="projectMeetingQuery">
        /// The project meeting query.
        /// </param>
        /// <returns>
        /// The <see cref="IResult"/>.
        /// </returns>
        public IResult ExecuteSearchQuery(ProjectMeetingQuery projectMeetingQuery)
        {
            SearchSettings settings = projectMeetingQuery.Settings;
            var result = new ProjectMeetingResult();

            IQueryOver<ProjectMeeting, ProjectMeeting> search =
                this.Session.QueryOver<ProjectMeeting>().Fetch(x => x.Status).Eager;
            this.ApplyDefaultCriterias(settings, search);
            this.ApplyDefaultSearchFieldCriteriasReportsSearch(projectMeetingQuery.DefaultFields, search);

            if (projectMeetingQuery.AtLocation.HasValue && projectMeetingQuery.AtLocation.Value != Guid.Empty)
            {
                search = search.Where(x => x.Location.ID == projectMeetingQuery.AtLocation.Value);
            }

            var statusSearch = this.Session.QueryOver<ProjectMeetingStatus>();
            bool hasStatusCriterion = false;

            if (projectMeetingQuery.Profiles != null && projectMeetingQuery.Profiles.Any())
            {
                search.RootCriteria.CreateAlias("Participants", "prs")
                         .Add(Restrictions.In("prs.ID", projectMeetingQuery.Profiles));
            }

            if (projectMeetingQuery.WithDemonstration.HasValue && projectMeetingQuery.WithDemonstration.Value != Guid.Empty)
            {
                hasStatusCriterion = true;
                var demoList = new List<Guid>()
                {
                    projectMeetingQuery.WithDemonstration.Value
                };
                statusSearch.RootCriteria.CreateAlias("Demonstrations", "demos")
                          .Add(Restrictions.In("demos.ID", demoList));
            }

            if (projectMeetingQuery.WithRole.HasValue && projectMeetingQuery.WithRole.Value != Guid.Empty)
            {
                hasStatusCriterion = true;
                var roleList = new List<Guid>()
                {
                    projectMeetingQuery.WithRole.Value
                };
                statusSearch.RootCriteria.CreateAlias("Roles", "ro")
                          .Add(Restrictions.In("ro.ID", roleList));
            }

            if (projectMeetingQuery.WithProjectType.HasValue && projectMeetingQuery.WithProjectType.Value != Guid.Empty)
            {
                hasStatusCriterion = true;
                statusSearch = statusSearch.Where(x => x.Type.ID == projectMeetingQuery.WithProjectType.Value);
            }

            if (projectMeetingQuery.WithStatus.HasValue && projectMeetingQuery.WithStatus.Value != Enums.ProjectMeetingStatusType.None)
            {
                hasStatusCriterion = true;
                statusSearch = statusSearch.Where(x => x.StatusType == projectMeetingQuery.WithStatus.Value);
            }

            if (hasStatusCriterion)
            {
                var statusIds = statusSearch.List();
                search = search.WhereRestrictionOn(x => x.Status).IsInG(statusIds);
            }

            var profilesAreAtRemoteArea = projectMeetingQuery.ProfilesAreAtRemoteArea ?? false;
            var profilesAreEntrepreneur = projectMeetingQuery.ProfilesAreEntrepreneur ?? false;
            if (profilesAreAtRemoteArea || profilesAreEntrepreneur)
            {
                var searchProfiles = this.Session.QueryOver<Models.Domain.Profile>();

                if (profilesAreAtRemoteArea)
                {
                    searchProfiles = searchProfiles.Where(x => x.IsRemoteArea);
                }

                if (profilesAreEntrepreneur)
                {
                    searchProfiles = searchProfiles.Where(x => x.IsEntrepreneur);
                }

                var profileList = searchProfiles.List().Select(x => x.ID);

                if (profileList.Any())
                {
                    search.RootCriteria.CreateAlias("Participants", "atprof")
                          .Add(Restrictions.In("atprof.ID", profileList.ToArray()));
                }
                else
                {
                    //No profiles match the search, force return 0 results
                    search = search.Where(x => x.ID == Guid.Empty);
                }
            }


            result.TotalRowCount = search.RowCount();
            var list = ApplySkipAndTake(settings, this.Sort(settings, search.List()));

            var projectMeetings = list as IList<ProjectMeeting> ?? list.ToList();
            if (projectMeetings.Any())
            {
                foreach (ProjectMeeting meeting in list)
                {
                    result.List.Add(Services.Dto.ProjectMeeting.Convert(meeting));
                }
            }

            return result;
        }

        #endregion

        #region Methods

        /// <summary>
        /// The create project meeting.
        /// </summary>
        /// <param name="cmd">
        /// The cmd.
        /// </param>
        internal void CreateProjectMeeting(CreateProjectMeetingCommand cmd)
        {
            if (cmd.ProjectMeeting != null)
            {
                var meeting = new ProjectMeeting
                                  {
                                      ID = cmd.ProjectMeeting.ID, 
                                      IsNational = cmd.ProjectMeeting.IsNational, 
                                      TimeOfActivity = cmd.ProjectMeeting.Date, 
                                      Location = this.Session.Get<Location>(cmd.ProjectMeeting.LocationID), 
                                      Name = cmd.ProjectMeeting.Name, 
                                      Owner = this.Session.Get<Project>(cmd.ProjectMeeting.OwnerID), 
                                      
                                  };

                if (cmd.ProjectMeeting.OwnerProjects != null && cmd.ProjectMeeting.OwnerProjects.Any())
                {
                    meeting.OwnerProjects = new HashSet<Project>();
                    foreach (Guid prID in cmd.ProjectMeeting.OwnerProjects)
                    {
                        var project = this.Session.Get<Project>(prID);
                        if (project != null)
                        {
                            meeting.OwnerProjects.Add(project);
                        }
                    }
                }


                if (cmd.ProjectMeeting.Groups != null && cmd.ProjectMeeting.Groups.Any())
                {
                    meeting.Groups = new HashSet<Group>();
                    foreach (Guid prID in cmd.ProjectMeeting.Groups)
                    {
                        var group = this.Session.Get<Group>(prID);
                        if (group != null)
                        {
                            meeting.Groups.Add(group);
                        }
                    }
                }

                if (cmd.ProjectMeeting.Status != null)
                {
                    Services.Dto.ProjectMeetingStatus newStatus = cmd.ProjectMeeting.Status;

                    var status = new ProjectMeetingStatus
                                     {
                                         ID = newStatus.ID, 
                                         ApplicationAboutText = newStatus.ApplicationAboutText, 
                                         Description = newStatus.Description, 
                                         FinancingText = newStatus.FinancingText, 
                                         GuidanceAboutText = newStatus.GuidanceAboutText, 
                                         IsExternal = newStatus.IsExternal, 
                                         PatentName = newStatus.PatentName, 
                                         StatusOfProject = newStatus.StatusOfProject, 
                                         Type = this.Session.Get<ProjectType>(newStatus.Type),
                                         StatusType = newStatus.StatusType
                                     };

                    if (newStatus.DemonstrationIDs != null && newStatus.DemonstrationIDs.Any())
                    {
                        status.Demonstrations = new HashSet<ProjectMeetingDemonstration>();
                        foreach (Guid demoID in newStatus.DemonstrationIDs)
                        {
                            var demo = this.Session.Get<ProjectMeetingDemonstration>(demoID);
                            if (demo != null)
                            {
                                status.Demonstrations.Add(demo);
                            }
                        }
                    }

                    if (newStatus.ApplicationAbout != null && newStatus.ApplicationAbout.Any())
                    {
                        status.ApplicationAbout = new List<Fund>();
                        foreach (Guid appID in newStatus.ApplicationAbout)
                        {
                            var fund = this.Session.Get<Fund>(appID);
                            if (fund != null)
                            {
                                status.ApplicationAbout.Add(fund);
                            }
                        }
                    }

                    if (newStatus.GuidanceAbout != null && newStatus.GuidanceAbout.Any())
                    {
                        status.GuidanceAbout = new List<Fund>();
                        foreach (Guid appID in newStatus.GuidanceAbout)
                        {
                            var fund = this.Session.Get<Fund>(appID);
                            if (fund != null)
                            {
                                status.GuidanceAbout.Add(fund);
                            }
                        }
                    }

                    if (newStatus.Financing != null && newStatus.Financing.Any())
                    {
                        status.Financing = new List<Fund>();
                        foreach (Guid appID in newStatus.Financing)
                        {
                            var fund = this.Session.Get<Fund>(appID);
                            if (fund != null)
                            {
                                status.Financing.Add(fund);
                            }
                        }
                    }

                    if (newStatus.Roles != null && newStatus.Roles.Any())
                    {
                        status.Roles = new List<ProjectMeetingRole>();
                        foreach (Guid appID in newStatus.Roles)
                        {
                            var role = this.Session.Get<ProjectMeetingRole>(appID);
                            if (role != null)
                            {
                                status.Roles.Add(role);
                            }
                        }
                    }

                    meeting.Status = status;

                    CreateProjectMeeting(meeting);
                }
            }
        }

        /// <summary>
        /// The delete project meeting.
        /// </summary>
        /// <param name="cmd">
        /// The cmd.
        /// </param>
        internal void DeleteProjectMeeting(DeleteProjectMeetingCommand cmd)
        {
            if (cmd.Dto != Guid.Empty)
            {
                var meeting = this.Session.Get<ProjectMeeting>(cmd.Dto);
                if (meeting != null)
                {
                    this.Log.CreateLogEntry(
                        meeting.ID,
                        string.Format("Projekt-aktivitet '{0}' blev slettet.", meeting.Name),
                        Enums.LogEntryType.ProjectMeeting,
                        Enums.LogEntryActionType.Delete);

                    if (meeting.Status != null)
                    {
                        this.Session.Delete(meeting.Status);
                    }
                    
                    this.Session.Delete(meeting);
                }
            }
        }

        /// <summary>
        /// The query all demonstrations.
        /// </summary>
        /// <returns>
        /// The <see cref="IResult"/>.
        /// </returns>
        internal IResult QueryAllDemonstrations()
        {
            var result = new ProjectMeetingDemonstrationResult();

            var list =
                this.Session.QueryOver<ProjectMeetingDemonstration>().List().OrderBy(x => x.Name);
            result.TotalRowCount = list.Count();
            foreach (ProjectMeetingDemonstration demo in list)
            {
                result.List.Add(Services.Dto.ProjectMeetingDemonstration.Convert(demo));
            }

            return result;
        }

        /// <summary>
        /// The query all funds.
        /// </summary>
        /// <returns>
        /// The <see cref="IResult"/>.
        /// </returns>
        internal IResult QueryAllFunds()
        {
            var result = new FundResult();

            IOrderedEnumerable<Fund> list = this.Session.QueryOver<Fund>().List().OrderBy(x => x.Name);
            result.TotalRowCount = list.Count();
            foreach (Fund fund in list)
            {
                result.List.Add(Services.Dto.Fund.Convert(fund));
            }

            return result;
        }

        /// <summary>
        /// The query all groups.
        /// </summary>
        /// <returns>
        /// The <see cref="IResult"/>.
        /// </returns>
        internal IResult QueryAllGroups()
        {
            var result = new GroupResult();

            IOrderedEnumerable<Group> list = this.Session.QueryOver<Group>().List().OrderBy(x => x.Name);
            result.TotalRowCount = list.Count();
            foreach (Group type in list)
            {
                result.List.Add(Services.Dto.Group.Convert(type));
            }

            return result;
        }

        /// <summary>
        /// The query all project types.
        /// </summary>
        /// <returns>
        /// The <see cref="IResult"/>.
        /// </returns>
        internal IResult QueryAllProjectTypes()
        {
            var result = new ProjectTypeResult();

            IOrderedEnumerable<ProjectType> list = this.Session.QueryOver<ProjectType>().List().OrderBy(x => x.Name);
            result.TotalRowCount = list.Count();
            foreach (ProjectType type in list)
            {
                result.List.Add(Services.Dto.ProjectType.Convert(type));
            }

            return result;
        }

        /// <summary>
        /// The query all roles.
        /// </summary>
        /// <returns>
        /// The <see cref="IResult"/>.
        /// </returns>
        internal IResult QueryAllRoles()
        {
            var result = new ProjectMeetingRoleResult();

            IOrderedEnumerable<ProjectMeetingRole> list =
                this.Session.QueryOver<ProjectMeetingRole>().List().OrderBy(x => x.Name);
            result.TotalRowCount = list.Count();
            foreach (ProjectMeetingRole role in list)
            {
                result.List.Add(Services.Dto.ProjectMeetingRole.Convert(role));
            }

            return result;
        }

        /// <summary>
        /// The update project meeting.
        /// </summary>
        /// <param name="cmd">
        /// The cmd.
        /// </param>
        internal void UpdateProjectMeeting(UpdateProjectMeetingCommand cmd)
        {
            if (cmd.Dto != null)
            {
                var meeting = this.Session.Get<ProjectMeeting>(cmd.Dto.ID);
                if (meeting != null)
                {
                    meeting.IsNational = cmd.Dto.IsNational;
                    meeting.TimeOfActivity = cmd.Dto.Date;
                    meeting.Location = this.Session.Get<Location>(cmd.Dto.LocationID);
                    meeting.Name = cmd.Dto.Name;
                    meeting.Owner = this.Session.Get<Project>(cmd.Dto.OwnerID);
                    

                    if (cmd.Dto.OwnerProjects != null && cmd.Dto.OwnerProjects.Any())
                    {
                        meeting.OwnerProjects.Clear();
                        foreach (Guid prID in cmd.Dto.OwnerProjects)
                        {
                            var project = this.Session.Get<Project>(prID);
                            if (project != null)
                            {
                                meeting.OwnerProjects.Add(project);
                            }
                        }
                    }

                    if (cmd.Dto.Participants != null && cmd.Dto.Participants.Any())
                    {
                        meeting.Participants.Clear();
                        foreach (Guid prID in cmd.Dto.Participants)
                        {
                            var profile = this.Session.Get<Profile>(prID);
                            if (profile != null)
                            {
                                meeting.Participants.Add(profile);
                            }
                        }
                    }


                    if (cmd.Dto.Groups != null && cmd.Dto.Groups.Any())
                    {
                        meeting.Groups = new HashSet<Group>();
                        foreach (Guid prID in cmd.Dto.Groups)
                        {
                            var group = this.Session.Get<Group>(prID);
                            if (group != null)
                            {
                                meeting.Groups.Add(group);
                            }
                        }
                    }


                    if (cmd.Dto.Status != null)
                    {
                        if (meeting.Status != null)
                        {
                            this.Session.Delete(meeting.Status);
                            meeting.Status = null;
                            this.Session.Update(meeting);
                        }

                        meeting.Status = this.CreateProjectMeetingStatus(cmd.Dto.Status);

                        this.Session.Update(meeting);

                        this.Log.CreateLogEntry(
                            meeting.ID,
                            string.Format("Projekt-aktivitet '{0}' blev opdateret.", meeting.Name),
                            Enums.LogEntryType.ProjectMeeting,
                            Enums.LogEntryActionType.Update);
                    }
                }
            }
        }

        /// <summary>
        /// The create project meeting status.
        /// </summary>
        /// <param name="newStatus">
        /// The new status.
        /// </param>
        /// <returns>
        /// The <see cref="ProjectMeetingStatus"/>.
        /// </returns>
        private ProjectMeetingStatus CreateProjectMeetingStatus(Services.Dto.ProjectMeetingStatus newStatus)
        {
            var status = new ProjectMeetingStatus
                             {
                                 ID = newStatus.ID, 
                                 ApplicationAboutText = newStatus.ApplicationAboutText, 
                                 Description = newStatus.Description, 
                                 FinancingText = newStatus.FinancingText, 
                                 GuidanceAboutText = newStatus.GuidanceAboutText, 
                                 IsExternal = newStatus.IsExternal, 
                                 PatentName = newStatus.PatentName, 
                                 StatusOfProject = newStatus.StatusOfProject,
                                 StatusType = newStatus.StatusType,
                                 
                             };

            if (newStatus.Type != null && newStatus.Type != Guid.Empty)
            {
                var projectType = this.Session.Get<ProjectType>(newStatus.Type);
                if (projectType != null)
                {
                    status.Type = projectType;
                }
            }

            if (newStatus.DemonstrationIDs != null && newStatus.DemonstrationIDs.Any())
            {
                status.Demonstrations = new HashSet<ProjectMeetingDemonstration>();
                foreach (Guid demoID in newStatus.DemonstrationIDs)
                {
                    var demo = this.Session.Get<ProjectMeetingDemonstration>(demoID);
                    if (demo != null)
                    {
                        status.Demonstrations.Add(demo);
                    }
                }
            }

            if (newStatus.ApplicationAbout != null && newStatus.ApplicationAbout.Any())
            {
                foreach (Guid appID in newStatus.ApplicationAbout)
                {
                    var fund = this.Session.Get<Fund>(appID);
                    if (fund != null)
                    {
                        status.ApplicationAbout.Add(fund);
                    }
                }
            }

            if (newStatus.GuidanceAbout != null && newStatus.GuidanceAbout.Any())
            {
                foreach (Guid appID in newStatus.GuidanceAbout)
                {
                    var fund = this.Session.Get<Fund>(appID);
                    if (fund != null)
                    {
                        status.GuidanceAbout.Add(fund);
                    }
                }
            }

            if (newStatus.Financing != null && newStatus.Financing.Any())
            {
                foreach (Guid appID in newStatus.Financing)
                {
                    var fund = this.Session.Get<Fund>(appID);
                    if (fund != null)
                    {
                        status.Financing.Add(fund);
                    }
                }
            }

            if (newStatus.Roles != null && newStatus.Roles.Any())
            {
                foreach (Guid appID in newStatus.Roles)
                {
                    var role = this.Session.Get<ProjectMeetingRole>(appID);
                    if (role != null)
                    {
                        status.Roles.Add(role);
                    }
                }
            }

            this.Session.Save(status);

            return status;
        }

        /// <summary>
        /// The sort.
        /// </summary>
        /// <param name="settings">
        /// The settings.
        /// </param>
        /// <param name="search">
        /// The search.
        /// </param>
        /// <returns>
        /// The sorted list of project meetings.
        /// </returns>
        private IOrderedEnumerable<ProjectMeeting> Sort(SearchSettings settings, IEnumerable<ProjectMeeting> search)
        {
            bool asc = settings.SortAscending == null ? true : (bool)settings.SortAscending;

            if (settings.OrderBy != null)
            {
                switch (settings.OrderBy)
                {
                    case "Location.Name":
                        return asc
                                   ? search.OrderBy(x => x.Location.Name)
                                   : search.OrderByDescending(x => x.Location.Name);
                    case "Name":
                        return asc ? search.OrderBy(x => x.Name) : search.OrderByDescending(x => x.Name);
                    case "Status.Type":
                        return asc ? search.OrderBy(x => x.Status.Type) : search.OrderByDescending(x => x.Status.Type);
                    case "Status.PatentName":
                        return asc
                                   ? search.OrderBy(x => x.Status.PatentName)
                                   : search.OrderByDescending(x => x.Status.PatentName);

                        // Add more orderbys
                }
            }

            return asc ? search.OrderBy(x => x.TimeOfActivity) : search.OrderByDescending(x => x.TimeOfActivity);
        }

        #endregion
    }
}